﻿using System;
using System.Text;
using System.Collections;
using System.DirectoryServices;

/// <summary>
///LdapAuthentication 的摘要说明
/// </summary>
public class LdapAuthentication
{
    private string _path;
    private string _filterAttribute;
    public string user;
    public string name;
    public string bm;
    public string dw;
    public string sex;
    public string worktype;
    public string telephoneNumber;
    public string department;
    public string title;
    public string displayname;
    public string group;
    public string userOU;
    public string disn;

    public LdapAuthentication()
    {

    }
    public LdapAuthentication(string path)
    {
        _path = path;
    }

    public bool IsAuthenticated(string domain, string username, string pwd)
    {
        string domainAndUsername = domain + @"\" + username;
        DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
        try
        {
            // Bind to the native AdsObject to force authentication. 
            Object obj = entry.NativeObject;
            DirectorySearcher search = new DirectorySearcher(entry);
            search.Filter = "(SAMAccountName=" + username + ")";

            search.PropertiesToLoad.Add("cn");
            search.PropertiesToLoad.Add("name");
            search.PropertiesToLoad.Add("title");
            search.PropertiesToLoad.Add("displayname");
            search.PropertiesToLoad.Add("telephoneNumber");
            search.PropertiesToLoad.Add("mail");
            search.PropertiesToLoad.Add("department");
            search.PropertiesToLoad.Add("memberOf");
            search.PropertiesToLoad.Add("SAMAccountName");
            search.PropertiesToLoad.Add("distinguishedName");
            search.PropertiesToLoad.Add("ou");

            SearchResult result = search.FindOne();

            if (result == null)
            {
                return false;
            }
            System.DirectoryServices.PropertyCollection prop = result.GetDirectoryEntry().Properties;

            // Update the new path to the user in the directory
            _path = result.Path;
            _filterAttribute = (String)result.Properties["cn"][0];

            user = (string)result.Properties["SAMAccountName"][0];

            name = (string)result.Properties["name"][0];

            object o = prop["department"].Value;
            department = o == null ? "" : o.ToString();
            if (department != "")
            {
                string[] aryDepartment = department.Split('.');
                dw = aryDepartment[0];
                if (aryDepartment.Length > 1)
                {
                    bm = aryDepartment[1];
                }

            }

            o = prop["title"].Value;
            title = o == null ? "" : o.ToString();

            o = prop["telephoneNumber"].Value;
            telephoneNumber = o == null ? "" : o.ToString();

            o = prop["displayname"].Value;
            displayname = o == null ? "" : o.ToString();
            if (displayname != "")
            {
                string[] aryDisplay = displayname.Split('.');
                sex = aryDisplay[0];
                if (sex != "男" && sex != "女")
                {
                    sex = "男";
                }
                worktype = "";
                if (aryDisplay.Length > 1)
                {
                    worktype = aryDisplay[1];
                }
            }
            o = prop["distinguishedName"].Value;
            disn = o == null ? "" : o.ToString();

            StringBuilder groupNames = new StringBuilder();
            int propertyCount = result.Properties["memberOf"].Count;
            String dn;
            int equalsIndex, commaIndex;

            for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
            {
                dn = (String)result.Properties["memberOf"][propertyCounter];

                equalsIndex = dn.IndexOf("=", 1);
                commaIndex = dn.IndexOf(",", 1);
                if (-1 == equalsIndex)
                {
                    return false;
                }
                groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
                groupNames.Append("|");
            }
            group = groupNames.ToString();
        }
        catch (Exception ex)
        {
            //throw new Exception("对用户进行身份验证时出错。 " + ex.Message);
            return false;
        }

        return true;
    }

    public string GetGroups()
    {
        DirectorySearcher search = new DirectorySearcher(_path);
        search.Filter = "(cn=" + _filterAttribute + ")";
        search.PropertiesToLoad.Add("memberOf");
        StringBuilder groupNames = new StringBuilder();
        try
        {
            SearchResult result = search.FindOne();
            int propertyCount = result.Properties["memberOf"].Count;
            String dn;
            int equalsIndex, commaIndex;

            for (int propertyCounter = 0; propertyCounter < propertyCount;
                propertyCounter++)
            {
                dn = (String)result.Properties["memberOf"][propertyCounter];

                equalsIndex = dn.IndexOf("=", 1);
                commaIndex = dn.IndexOf(",", 1);
                if (-1 == equalsIndex)
                {
                    return null;
                }
                groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
                groupNames.Append("|");
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error obtaining group names. " + ex.Message);
        }
        return groupNames.ToString();
    }
}
